﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
using Cgd.Shell.Data;
using Rss = RssToolkit.Rss;

namespace Cgd.Shell.RssService
{
	public partial class RssService : ServiceBase
	{
		public RssService()
		{
			InitializeComponent();
		}

		const string LogSource = "Cgd Shell Rss Service";
		const string LogName = "CgdLog";

		EventLog theLog = null;
		Timer theTimer = null;

		protected override void OnStart(string[] args)
		{
			InitLog();
			InitTimer();
			theLog.WriteInformation("RSS抓取服务已成功启动。");
		}

		protected override void OnStop()
		{
			theLog.WriteInformation("RSS抓取服务已终止。");
			DisposeTimer();
			DisposeLog();
		}

		private void InitLog()
		{
			if (!EventLog.SourceExists(LogSource))
				EventLog.CreateEventSource(LogSource, LogName);

			theLog = new EventLog(LogName, ".", LogSource);
		}

		private void DisposeLog()
		{
			if (theLog != null)
			{
				theLog.Dispose();
				theLog = null;
			}
		}

		private void InitTimer()
		{
			theTimer = new Timer(15 * 60 *1000);
			theTimer.AutoReset = false;
			theTimer.Elapsed += new ElapsedEventHandler(theTimer_Elapsed);
			theTimer.Start();
		}

		private void DisposeTimer()
		{
			if (theTimer != null)
			{
				theTimer.Dispose();
				theTimer = null;
			}
		}

		void theTimer_Elapsed(object sender, ElapsedEventArgs e)
		{
			try
			{
				ReadAllRssFeeds();
				theLog.WriteInformation("已完成本轮抓取，等待下一次抓取。");
			}
			catch(Exception ex)
			{
				theLog.WriteError("本轮抓取出现错误：\r\n" + ex.ToString());
			}

			theTimer.Start();
		}

		private void ReadAllRssFeeds()
		{
			using (CgdShellDataContext db = new CgdShellDataContext())
			{
				foreach (RssFeed feed in db.RssFeeds)
				{
					try
					{
						int validItems = 0;
						DateTime lastReadTime = DateTime.Now;
						Rss.RssDocument rssdoc = Rss.RssDocument.Load(new Uri(feed.Url));

						foreach (Rss.RssItem item in rssdoc.Channel.Items)
						{
							if (item.PubDateParsed > feed.LastReadTime)
							{
								RssDocument doc = new RssDocument()
								{
									Id = Guid.NewGuid(),
									RssFeedId = feed.Id,
									Title = item.Title ?? "",
									Summary = item.Description ?? "",
									Url = item.Link ?? ""
								};

								db.RssDocuments.InsertOnSubmit(doc);
								validItems++;
							}
						}
						feed.LastReadTime = lastReadTime;
						db.SubmitChanges();
					}
					catch (Exception ex)
					{
						theLog.WriteError(string.Format(
							"在抓取RSS源 {0} ({1}, {2}) 时发生错误：\r\n{3}",
							feed.Id,
							feed.Title,
							feed.Url,
							ex.Message));
					}
				}
			}
		}
	}
}
